package com.ctsi.commons.util.zip;

import com.ctsi.commons.util.UtilFile;
import com.ctsi.commons.util.UtilValidate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class UnzipImpl implements Unzip {
	private static Logger log = LoggerFactory.getLogger(UnzipImpl.class);

	public void doUnzip(String fileName) throws Exception {
		File f = new File(fileName);
		String fileDir = f.getParent();
		log.debug("path is {}", fileDir);
		doUnzip(fileName, fileDir);

	}

	public void doUnzip(String fileName, String dir) throws Exception {

		// 文件输入流
		FileInputStream fi = new FileInputStream(fileName);
		doUnzip(fi, dir);
	}

	protected void createDirectory(String directory, String subDirectory) {

		String dir[];
		File fl = new File(directory);
		try {
			if (UtilValidate.isEmpty(subDirectory) && !fl.exists())
				fl.mkdir();
			else if (UtilValidate.isNotEmpty(subDirectory)) {
				dir = subDirectory.replace('\\', '/').split("/");

				for (int i = 0; i < dir.length; i++) {
					File subFile = new File(directory + File.separator + dir[i]);
					if (!subFile.exists()) {

						subFile.mkdir();
					}

					directory += File.separator + dir[i];
				}
			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
			throw new RuntimeException(ex);
		}
	}

	public void doUnzip(InputStream fi, String dir) throws Exception {

		// int i=fileName.lastIndexOf(".");
		// String fileDir=fileName.substring(0,i);
		ZipInputStream zipin = null;

		// 输入流检查
		CheckedInputStream csi = new CheckedInputStream(fi, new Adler32());
		// 输入流压缩
		zipin = new ZipInputStream(csi);
		ZipEntry ze;
		// 解压全部文件
		// byte[] buffer=new byte[4096];
		try {
			while ((ze = zipin.getNextEntry()) != null) {
				if (ze.isDirectory()) {
					File f = new File(dir + "/" + ze.getName());
					if (!f.exists())
						f.mkdirs();
				} else {

					String fn = ze.getName();
					fn = fn.replace('\\', '/');

					if (fn.indexOf("/") != -1) {

						createDirectory(dir, fn.substring(0, fn.lastIndexOf("/")));
					}
					File f = new File(dir + "/" + fn);
					f.createNewFile();

					OutputStream out = new FileOutputStream(f);

					try {
						UtilFile.copyNoClose(zipin, out);
					} finally {
						out.close();
					}

				}
			}
		} finally {
			if (zipin != null)
				zipin.close();
		}

	}
}
